package com.ruoyi.Amount.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.Amount.domain.DTO.OrderSubmitDTO;
import com.ruoyi.Amount.domain.VO.OrderSubmitVO;
import com.ruoyi.Amount.mapper.OrderMapper;
import com.ruoyi.Amount.result.Result;
import com.ruoyi.Amount.service.AmountReduce;
import com.ruoyi.agent.domain.SysAgent;
import com.ruoyi.agent.mapper.SysAgentMapper;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.order.domain.SysOrderOne;
import com.ruoyi.order.service.ISysOrderOneService;
import com.ruoyi.orderParent.domain.SysOrderParent;
import com.ruoyi.orderParent.service.ISysOrderParentService;
import com.ruoyi.store.domain.SysStore;
import com.ruoyi.store.mapper.SysStoreMapper;
import com.ruoyi.storeExpend.domain.StoreExpend;
import com.ruoyi.storeExpend.service.IStoreExpendService;
import org.apache.ibatis.jdbc.Null;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Random;
@Service
public class AmountReduceImpl implements AmountReduce {

    @Autowired
    private ISysOrderOneService iSysOrderOneService;
    @Autowired
    private SysStoreMapper sysStoreMapper;
    @Autowired
    private IStoreExpendService iStoreExpendService;
    @Autowired
    private SysAgentMapper sysAgentMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ISysOrderParentService iSysOrderParentService;


    /**
     * 返回预支付效验单
     *
     * @param ordersSubmitDTO
     * @return
     */
    @Transactional
    public OrderSubmitVO submitOrder(OrderSubmitDTO ordersSubmitDTO) {

        //构造订单数据
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        BeanUtils.copyProperties(ordersSubmitDTO,orderSubmitVO);
        //订单编号
        orderSubmitVO.setNumber(String.valueOf(System.currentTimeMillis()));
        //订单状态
        orderSubmitVO.setOrderStatus(0L);
        //用户id
        orderSubmitVO.setUserId(185l);
        //部门id
        orderSubmitVO.setDeptId(274l);
        //总金额=单价*人数    allamount=amount*cdNumber
        BigDecimal allamount = ordersSubmitDTO.getAmount().multiply(BigDecimal.valueOf(ordersSubmitDTO.getCdNumber()));
        orderSubmitVO.setAllamount(allamount);

        //插入商户id
        long userId = 185l;
        long storeId = orderMapper.getStoreId(userId);

        orderSubmitVO.setStoreId(storeId);
        //查询商户可用余额 balance
        BigDecimal storeBalance = orderMapper.getStoreBalance(storeId);
        //插入余额
        orderSubmitVO.setBalance(storeBalance);

        //如果有代理商，则插入代理商id
        long agentId = orderMapper.getAgentId(storeId);
        if (ObjectUtil.isNotEmpty(agentId)){
            orderSubmitVO.setAgentId(agentId);
/*            //代理商可用余额 balance
            BigDecimal agentBalance = orderMapper.getAgentBalance(agentId);*/
        }

        return orderSubmitVO;
    }


    /**
     * 单人背调下单，支付
     *
     * @param orderSubmitVO
     * @return
     */
    public Result onePayment(OrderSubmitVO orderSubmitVO) throws Exception {

        //判断商户可用余额 balance是否大于0
        BigDecimal storeBalance = orderSubmitVO.getBalance();
        // 使用compareTo方法检查余额是否大于0
        if (storeBalance.compareTo(BigDecimal.ZERO) <= 0) {
            return Result.error("支付失败，当前账户余额不足请联系管理员充值");
        }

        //如果有代理商，则判断代理商余额是否大于0
        long agentId = orderSubmitVO.getAgentId();
        //ObjectUtil.isEmpty(long)
        if (ObjectUtil.isNotEmpty(agentId)){
            //代理商可用余额 balance
            BigDecimal agentBalance = orderMapper.getAgentBalance(agentId);
            if (agentBalance.compareTo(BigDecimal.ZERO) <= 0){
                return Result.error("支付失败，请联系管理员");
            }
        }

        SysOrderOne order = new SysOrderOne();
        BeanUtils.copyProperties(orderSubmitVO,order);
        //1.向订单表插入1条数据
        iSysOrderOneService.insertSysOrderOne(order);

        //2.支付
          //获取当前登录用户id
        Long userId = SecurityUtils.getUserId();
          //获取所属商户id
        Long storeId = order.getStoreId();
          //判断发起背调的商户有代理商，对代理商扣钱
          //获取当前代理商id
/*        Long agentId = order.getAgentId();*/
        if(ObjectUtil.isEmpty(agentId)){
        //3.代理商扣钱
            //2.查询要充值的代理商是否存在
            SysAgent agent = sysAgentMapper.selectSysAgentById(agentId);
            // 2.1判断代理商是否存在
            if (agent == null) { // 检查返回的对象是否为null
                // 2.2 代理商不存在，无法进行充值操作
                return Result.error("代理商不存在，无法进行支付操作");
            }

            // 3. 创建一个 SysAgent 对象，设置新的余额，并保留原有的代理商 ID
            SysAgent agentToUpdate = new SysAgent();
            agentToUpdate.setId(agentId); // 这里需要替换为你要更新的商户的 ID
            //获取代理商接口价格之和
            BigDecimal exchangeAmount = orderMapper.getAgentTotalPrice(agentId);
            agentToUpdate.setBalance(exchangeAmount); // 把要增加的余额数量传过去  update sys_agent set balance =balance +- 1.00000000 where id =3

            // 调用更新方法
            int rowsAffected = sysAgentMapper.updateSysAgent(agentToUpdate);

            // 4. 判断是否更新成功
            if (rowsAffected <= 0) {
                // 如果没有行被影响，说明更新失败
                return Result.error("增加金额失败");
            }

            //5.创建充值明细单
            //5.1 封装要提交的数据
            StoreExpend storeExpend = new StoreExpend();
            //拷贝传入的参数
            BeanUtils.copyProperties(order,storeExpend);
            //生成交易标识id，十位数字和字母组成
            String ExchangeMark = getStringRandom(10);
            storeExpend.setExchangeMark(ExchangeMark);
            //授权类型为1商户
            storeExpend.setType(String.valueOf(1));
            //查询修改后金额
            storeExpend.setUserId(SecurityUtils.getUserId());
            storeExpend.setDeptId(SecurityUtils.getDeptId());
            //5.2调用创建消费明细单
            iStoreExpendService.insertStoreExpend(storeExpend);

        }

        //4.商户扣钱
        //2.查询要扣钱的商户是否存在
        SysStore store = sysStoreMapper.selectSysStoreById(storeId);
        // 2.1判断商户是否存在
        if (store == null) { // 检查返回的对象是否为null
            // 2.2 商户不存在，无法进行充值操作
            return Result.error("商户不存在，无法进行支付操作");
        }
        // 3. 创建一个 SysStore 对象，设置新的余额，并保留原有的商户 ID
        SysStore storeToUpdate = new SysStore();
        storeToUpdate.setId(storeId); // 这里需要替换为你要更新的商户的 ID
        BigDecimal exchangeAmount = order.getAmount();
        exchangeAmount = exchangeAmount.setScale(2,BigDecimal.ROUND_DOWN);
        exchangeAmount = exchangeAmount.negate();//变为负数
        storeToUpdate.setBalance(exchangeAmount); // 把要增加的余额数量传过去  update sys_store set balance =balance + -1.00000000 where id =3
        // 调用更新方法
        int rowsAffected = sysStoreMapper.updateSysStore(storeToUpdate);

        // 4. 判断是否更新成功
        if (rowsAffected <= 0) {
            // 如果没有行被影响，说明更新失败
            return Result.error("支付金额失败");
        }

        //5.创建充值明细单
        //5.1 封装要提交的数据
        StoreExpend storeExpend = new StoreExpend();
        //拷贝传入的参数
        BeanUtils.copyProperties(order,storeExpend);
        //记录的金额也是不四舍五入的
        storeExpend.setExchangeAmount(exchangeAmount);
        //生成交易标识id，十位数字和字母组成
        String ExchangeMark = getStringRandom(10);
        storeExpend.setExchangeMark(ExchangeMark);
        //授权类型为1商户
        storeExpend.setType(String.valueOf(1));
        storeExpend.setUserId(SecurityUtils.getUserId());
        storeExpend.setDeptId(SecurityUtils.getDeptId());
        //5.2调用创建消费明细单
        iStoreExpendService.insertStoreExpend(storeExpend);

        // 如果到达这里，说明更新成功
        return Result.success("金额增加成功");

    }

    /**
     * 生成交易标识id，十位数字和字母组成
     *
     * @param length
     * @return
     */
    public static String getStringRandom(int length) {
        String val = "";
        Random random = new Random();

        // 参数length，表示生成几位随机数
        for (int i = 0; i < length; i++) {

            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            // 输出字母还是数字
            if ("char".equalsIgnoreCase(charOrNum)) {
                // 输出是大写字母还是小写字母
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (random.nextInt(26) + temp);
            } else if ("num".equalsIgnoreCase(charOrNum)) {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }

    /**
     * 批量背调下单，支付
     *
     * @param orderSubmitVO
     * @return
     */
    public Result manyPayment(OrderSubmitVO orderSubmitVO){

        //判断商户可用余额 balance是否大于0
        BigDecimal storeBalance = orderSubmitVO.getBalance();
        // 使用compareTo方法检查余额是否大于0
        if (storeBalance.compareTo(BigDecimal.ZERO) <= 0) {
            return Result.error("支付失败，当前账户余额不足请联系管理员充值");
        }

        //如果有代理商，则判断代理商余额是否大于0
        long agentId = orderSubmitVO.getAgentId();
        //ObjectUtil.isEmpty(long)
        if (ObjectUtil.isNotEmpty(agentId)){
            //代理商可用余额 balance
            BigDecimal agentBalance = orderMapper.getAgentBalance(agentId);
            if (agentBalance.compareTo(BigDecimal.ZERO) <= 0){
                return Result.error("支付失败，请联系管理员");
            }
        }

        //插入批量订单表,同时把传过来的单人订单集合进行插入
        SysOrderParent orders = new SysOrderParent();
        BeanUtils.copyProperties(orderSubmitVO,orders);
        //1.调用批量插入数据业务
        iSysOrderParentService.insertSysOrderParent(orders);

        //2.支付
        //获取当前登录用户id
        Long userId = SecurityUtils.getUserId();
        //获取所属商户id
        Long storeId = orders.getStoreId();
        //判断发起背调的商户有代理商，对代理商扣钱
        //获取当前代理商id
        /*        Long agentId = order.getAgentId();*/
        if(ObjectUtil.isEmpty(agentId)){
            //3.代理商扣钱
            //2.查询要充值的代理商是否存在
            SysAgent agent = sysAgentMapper.selectSysAgentById(agentId);
            // 2.1判断代理商是否存在
            if (agent == null) { // 检查返回的对象是否为null
                // 2.2 代理商不存在，无法进行充值操作
                return Result.error("代理商不存在，无法进行支付操作");
            }

            // 3. 创建一个 SysAgent 对象，设置新的余额，并保留原有的代理商 ID
            SysAgent agentToUpdate = new SysAgent();
            agentToUpdate.setId(agentId); // 这里需要替换为你要更新的商户的 ID
            //获取代理商接口价格之和,并且乘以背调人数
            BigDecimal exchangeAmount = orderMapper.getAgentTotalPrice(agentId);
            Long cdNumber =orders.getCdNumber();
            BigDecimal totalPrice = BigDecimal.valueOf(cdNumber).multiply(exchangeAmount);
            agentToUpdate.setBalance(totalPrice); // 把要增加的余额数量传过去  update sys_agent set balance =balance +- 1.00000000 where id =3
            // 调用更新方法
            int rowsAffected = sysAgentMapper.updateSysAgent(agentToUpdate);

            // 4. 判断是否更新成功
            if (rowsAffected <= 0) {
                // 如果没有行被影响，说明更新失败
                return Result.error("增加金额失败");
            }

            //5.创建充值明细单
            //5.1 封装要提交的数据
            StoreExpend storeExpend = new StoreExpend();
            //拷贝传入的参数
            BeanUtils.copyProperties(orders,storeExpend);
            //生成交易标识id，十位数字和字母组成
            String ExchangeMark = getStringRandom(10);
            storeExpend.setExchangeMark(ExchangeMark);
            //授权类型为1商户
            storeExpend.setType(String.valueOf(1));
            //查询修改后金额
            storeExpend.setUserId(SecurityUtils.getUserId());
            storeExpend.setDeptId(SecurityUtils.getDeptId());
            //5.2调用创建消费明细单
            iStoreExpendService.insertStoreExpend(storeExpend);
        }

        //4.商户扣钱
        //2.查询要扣钱的商户是否存在
        SysStore store = sysStoreMapper.selectSysStoreById(storeId);
        // 2.1判断商户是否存在
        if (store == null) { // 检查返回的对象是否为null
            // 2.2 商户不存在，无法进行充值操作
            return Result.error("商户不存在，无法进行支付操作");
        }
        // 3. 创建一个 SysStore 对象，设置新的余额，并保留原有的商户 ID
        SysStore storeToUpdate = new SysStore();
        storeToUpdate.setId(storeId); // 这里需要替换为你要更新的商户的 ID
        BigDecimal exchangeAmount = orders.getAmount();//获取套餐单价
        Long cdNumber =orders.getCdNumber();//乘以背调人数
        exchangeAmount = BigDecimal.valueOf(cdNumber).multiply(exchangeAmount);
        exchangeAmount = exchangeAmount.setScale(2,BigDecimal.ROUND_DOWN);//不四舍五入，保留两位
        exchangeAmount = exchangeAmount.negate();//变为负数
        storeToUpdate.setBalance(exchangeAmount); // 把要增加的余额数量传过去  update sys_store set balance =balance + -1.00000000 where id =3
        // 调用更新方法
        int rowsAffected = sysStoreMapper.updateSysStore(storeToUpdate);

        // 4. 判断是否更新成功
        if (rowsAffected <= 0) {
            // 如果没有行被影响，说明更新失败
            return Result.error("支付金额失败");
        }

        //5.创建充值明细单
        //5.1 封装要提交的数据
        StoreExpend storeExpend = new StoreExpend();
        //拷贝传入的参数
        BeanUtils.copyProperties(orders,storeExpend);
        //记录的金额也是不四舍五入的
        storeExpend.setExchangeAmount(exchangeAmount);
        //生成交易标识id，十位数字和字母组成
        String ExchangeMark = getStringRandom(10);
        storeExpend.setExchangeMark(ExchangeMark);
        //授权类型为1商户
        storeExpend.setType(String.valueOf(1));
        storeExpend.setUserId(SecurityUtils.getUserId());
        storeExpend.setDeptId(SecurityUtils.getDeptId());
        //5.2调用创建消费明细单
        iStoreExpendService.insertStoreExpend(storeExpend);

        // 如果到达这里，说明更新成功
        return Result.success("金额增加成功");

    }

}
